using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using Microsoft.Practices.CompositeUI;

namespace SCSFContrib.CompositeUI.WPF
{
	/// <summary>
	/// Extends <see cref="WindowsApplication{TWorkItem, TShell}"/> to support WPF applications that use an <see cref="Application"/> as their
	/// shell.
	/// </summary>
	/// <remarks>
	/// <para>
	/// The <typeparamref name="TShell"/> type must extend <see cref="Application"/> and implement <see cref="IInitializeApplication"/>. Usually
	/// this interface implementation can simply be added to the partial class for a WPF application, since an <c>InitializeComponent</c> method
	/// is often automatically added by the compiler. If there is no compiler-generated <c>InitializeComponent</c> method, it can be simply added
	/// manually to the <see cref="Application"/> subclass.
	/// </para>
	/// </remarks>
	/// <typeparam name="TWorkItem">
	/// The type of the root application work item.
	/// </typeparam>
	/// <typeparam name="TShell">
	/// The type for the shell to use.
	/// </typeparam>
	/// <example>
	/// The following example shows how a simple subclass of <c>ApplicationShellApplication</c> can be created for a WPF CAB application. The root
	/// work item for the application will be of type <c>RootWorkItem</c>, whilst the WPF <c>Application</c> instance is of type <c>App</c>:
	/// <code>
	/// <![CDATA[
	/// public sealed class SimpleApplication : ApplicationShellApplication<RootWorkItem, App>
	/// {
	/// 	[STAThread]
	/// 	public static void Main()
	/// 	{
	/// 		//start up the CAB application
	/// 		new SimpleApplication().Run();
	/// 	}
	/// }
	/// ]]>
	/// </code>
	/// Note that this class defines the entry point for the application, which should be specified  when compiling the application. The simplest
	/// implementation of the <c>App</c> class is:
	/// <code>
	/// <![CDATA[
	/// public partial class App : System.Windows.Application, IInitializeApplication
	/// {
	/// }
	/// ]]>
	/// </code>
	/// Note the addition of the <c>IInitializeApplication</c> implementation. This is crucial in order for the type to be used by the
	/// <c>ApplicationShellApplication</c>. 
	/// </example>
	public abstract class ApplicationShellApplication<TWorkItem, TShell> : WindowsApplication<TWorkItem, TShell>
		where TWorkItem : WorkItem, new()
		where TShell : Application, IInitializeApplication, new()
	{
		/// <summary>
		/// Invoked after the shell is created.
		/// </summary>
		protected override void AfterShellCreated()
		{
			base.AfterShellCreated();
			Shell.InitializeComponent();
		}

		/// <summary>
		/// Invoked to start the CAB application.
		/// </summary>
		protected override void Start()
		{
			Shell.Run();
		}
	}
}